package fr.cephb.berkeleydb.dom;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

/**
 * A XML element
 * @author pierre
 *
 */
public class Element
	extends Node
	{
	private Document owner=null;
	private QName qName;
	private Map<QName,Attr> attributes=new HashMap<QName, Attr>();
	
	Element(long id,Document owner,QName qName)
		{
		super(id,owner);
		this.qName=qName;
		if(this.qName==null) throw new NullPointerException("qName");
		}
	
	public String getNamespaceURI()
		{
		return this.qName.getNamespaceURI();
		}
	
	Element(long id,Document owner,QName qName,List<Attr> atts)
		{
		this(id,owner,qName);
		if(atts!=null)
			{
			for(Attr att:atts)
				{
				this.attributes.put(att.getQName(), att);
				}
			}
		}
	
	public Attr[] getAttributes()
		{
		return this.attributes.values().toArray(new Attr[this.attributes.size()]);
		}
	
	public void setAttribute(String name,String value)
		{
		setAttribute(new QName(null,null,name),value);
		}
	
	public void setAttribute(QName name,String value)
		{
		this.attributes.put(name, new Attr(name, value));
		synch();
		}
	
	public String getAttribute(String name)
		{
		Attr att= getAttributeNode(name);
		return att==null?"":att.getValue();
		}
	
	public Attr getAttributeNode(String name)
		{
		return getAttributeNode(new QName(null,null,name));
		}
	
	public Attr getAttributeNode(QName qName)
		{
		return this.attributes.get(qName);
		}
	
	public String getLocalName()
		{
		return this.qName.getLocalPart();
		}
	public QName getQName()
		{
		return this.qName;
		}
	
	public String getNodeName()
		{
		if(getPrefix()!=null) return getPrefix()+":"+getLocalName();
		return getLocalName();
		}
	
	public String getPrefix()
		{
		return this.qName.getPrefix();
		}
	
	@Override
	public Document getOwnerDocument()
		{
		return this.owner;
		}
	
	@Override
	public int getNodeType()
		{
		return ELEMENT_NODE;
		}
	
	@Override
	public void write(XMLStreamWriter writer) throws XMLStreamException
		{
		if(this.first_child_id==-1L)
			{
			writer.writeEmptyElement(getPrefix(),getLocalName(),getNamespaceURI());
			writeAtts(writer);
			}
		else
			{
			writer.writeStartElement(getPrefix(),getLocalName(),getNamespaceURI());
			writeAtts(writer);
			Node curr= getFirstChild();
			while(curr!=null)
				{
				curr.write(writer);
				curr=curr.getNextSibling();
				}
			writer.writeEndElement();
			}
		}
	private void writeAtts(XMLStreamWriter writer)
	 	throws XMLStreamException
		{
		for(Attr att:this.attributes.values())
			{
			att.write(writer);
			}
		}
	
	@Override
	public String toString()
		{
		return "<"+getNodeName()+"/>";
		}
	}
